package com.ideaaedi.plugin.fastcoding.action;

import com.alibaba.fastjson.JSON;
import com.ideaaedi.commonds.exception.ExceptionUtil;
import com.ideaaedi.plugin.fastcoding.ui.MockJson_ChooseAndShowJson;
import com.ideaaedi.plugin.fastcoding.ui.MockJson_ShowJson;
import com.ideaaedi.plugin.fastcoding.util.NotifyUtil;
import com.ideaaedi.plugin.fastcoding.util.JdPsiClassUtil;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiParameter;
import com.intellij.psi.PsiType;
import com.intellij.psi.util.PsiTypesUtil;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 杀进程
 *
 * @author JustryDeng
 * @since 2021/12/18 9:10:51
 */
public class MockJsonAction extends AnAction {
    
    public static final String ACTION_NAME = "Mock Json";
    
    @Override
    public void actionPerformed(AnActionEvent event) {
        Project project = event.getData(PlatformDataKeys.PROJECT);
        if (project == null) {
            return;
        }
        try {
            PsiElement psiElementData = CommonDataKeys.PSI_ELEMENT.getData(event.getDataContext());
            if (psiElementData == null) {
                NotifyUtil.notify(project, ACTION_NAME, "Cannot find psiElementData.");
                return;
            }
            Set<PsiType> classNameWithGenericsSet = new LinkedHashSet<>();
            if (psiElementData instanceof PsiClass) {
                PsiClass psiClass = (PsiClass) psiElementData;
                classNameWithGenericsSet.add(PsiTypesUtil.getClassType(psiClass));
            } else if (psiElementData instanceof PsiMethod) {
                PsiMethod psiMethod = (PsiMethod) psiElementData;
                // 返回值的数据类型
                PsiType returnType = psiMethod.getReturnType();
                if (returnType != null) {
                    classNameWithGenericsSet.add(returnType);
                }
                // 参数的数据类型
                classNameWithGenericsSet.addAll(Arrays.stream(psiMethod.getParameterList().getParameters()).map(PsiParameter::getType).collect(Collectors.toSet())
                );
            } else {
                return;
            }
            
            int size = classNameWithGenericsSet.size();
            if (size == 0) {
                NotifyUtil.notify(project, ACTION_NAME, "未识别到类", NotificationType.INFORMATION);
            } else if (size == 1) {
                final PsiType psiType = classNameWithGenericsSet.iterator().next();
                String mockedJson = JSON.toJSONString(JdPsiClassUtil.mockClass(project, psiType));
                MockJson_ShowJson showJson = new MockJson_ShowJson(project, psiType.getPresentableText());
                showJson.jsonArea.setText(mockedJson);
                showJson.setVisible(true);
            } else {
                List<PsiType> typeList = new ArrayList<>(classNameWithGenericsSet);
                MockJson_ChooseAndShowJson showJson = new MockJson_ChooseAndShowJson(project, typeList);
                showJson.setVisible(true);
            }
        } catch (Exception e) {
            NotifyUtil.notify(project, ACTION_NAME, ExceptionUtil.getStackTraceMessage(e), NotificationType.ERROR);
        }
    }
}
